/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sv.com.intesal.compra.controlador;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import sv.com.intesal.clases.Mensaje;
import sv.com.intesal.clases.RutaProyecto;
import sv.com.intesal.clases.cVarios;
import sv.com.intesal.compra.bean.OrdenCompra;
import sv.com.intesal.compra.bean.SolicitudMaterial;
import sv.com.intesal.compra.sql.SQLOrdenCompra;
import sv.com.intesal.compra.sql.SQLSolicitudMaterial;
import sv.com.intesal.conexion.cConexion;
import sv.com.intesal.seguridad.bean.ParametroSicopi;
import sv.com.intesal.seguridad.controlador.BitacoraControlador;
import sv.com.intesal.seguridad.controlador.ParametroSicopiControlador;
import sv.com.intesal.seguridad.controlador.SessionControlador;

/**
 *
 * @author andrew
 */
public class OrdenCompraControlador {

    /* Orden de Compra */
    public List<SolicitudMaterial> fillOrdenCompraGrid() {
        List<SolicitudMaterial> list = new ArrayList<SolicitudMaterial>();
        try {
            ResultSet rs = cConexion.conectar().prepareStatement(SQLSolicitudMaterial.buscarSolicitudes).executeQuery();
            while (rs.next()) {
                SolicitudMaterial sm = new SolicitudMaterial();
                sm.setId_s(rs.getInt("id_s"));
                sm.setNumero_s(rs.getInt("numero_s"));
                sm.setSolicitante_s(rs.getString("solicitante_s"));
                sm.setDescripcion_s(rs.getString("descripcion_s"));
                sm.setFecha_s(rs.getDate("fecha_s"));
                sm.setCantidad_d(rs.getDouble("cantidad_d"));
                sm.setNombre_m(rs.getString("nombre_m"));
                sm.setId_dm(rs.getInt("id_dm"));
                sm.setId_d(rs.getInt("id_d"));
                list.add(sm);
            }
            rs.close();
            return list;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public void setEnca(OrdenCompra oc, List<OrdenCompra> lista) throws Exception {

        Connection cnn = null;
        PreparedStatement ps = null;
        try {

            cnn = cConexion.conectar();
            SessionControlador sc = new SessionControlador();
            ParametroSicopiControlador pc = new ParametroSicopiControlador();
            ParametroSicopi pp = pc.getParametroSicopi("ORDEN_COMPRA");
            cVarios v = new cVarios();

            if (oc.getId_oc() == null) {
                /*Proceso para Insertar una nueva orden*/
                ps = cnn.prepareStatement(SQLOrdenCompra.ingresarEncaOrdenCompra);

                ps.setInt(1, sc.getCodigo_Usuario());
                ps.setInt(2, oc.getId_em());
                ps.setInt(3, oc.getId_p());
                ps.setDate(4, cVarios.getFecha(oc.getFecha_oc()));
                ps.setInt(5, sc.getCodigo_Sucursal());
                ps.setString(6, oc.getTipo_oc());
                ps.setDouble(7, v.AproximarDecimal(oc.getPercepcion_oc()));

                ps.setInt(8, pp.getBloque_ps());
                ps.setInt(9, pp.getCorrelativo_ps());
                ps.setString(10, "P"); /*el estado es Pendiente por defecto*/

                ps.executeUpdate();

                //ACTUALIZAR NUMERO DE DOCUMENTO
                pc.updateCorrelativo("ORDEN_COMPRA");
            } else {
                /*Proceso para actualizar una oden ya existente*/
                ps = cnn.prepareStatement(SQLOrdenCompra.modificarOrdenCompra);

                ps.setInt(1, oc.getId_em());
                ps.setInt(2, oc.getId_p());

                ps.setInt(4, sc.getCodigo_Sucursal());
                ps.setString(5, oc.getTipo_oc());
                ps.setDouble(6, v.AproximarDecimal(oc.getPercepcion_oc()));

                ps.setInt(7, oc.getBloque_oc());
                ps.setInt(8, oc.getNumero_oc());
                ps.setInt(9, oc.getId_oc());
                ps.setDate(3, cVarios.getFecha(oc.getFecha_oc()));
                ps.executeUpdate();
            }



            this.setDeta(oc, lista);
            Mensaje m = new Mensaje();
            if (oc.getId_oc() == null) {
                m.messageInfo(m.getIinformation());
            } else {
                m.messageInfo(m.getImodificada());
            }
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    private void setDeta(OrdenCompra oc, List<OrdenCompra> lista) throws Exception {
        try {

            Integer codigo_oc = oc.getId_oc();
            if (oc.getId_oc() == null) {
                codigo_oc = this.getMax();
            }

            cVarios v = new cVarios();
            for (int i = 0; i < lista.size(); i++) {
                if (lista.get(i).getId_d() == 0) { //SI SOLO ES UN NUEVO REGISTRO
                /*Insertar Detalle de Orden de Compra*/
                    PreparedStatement ps = null;
                    Connection cnn = null;
                    cnn = cConexion.conectar();
                    ps = cnn.prepareStatement(SQLOrdenCompra.insertarDetaOrdenCompra);
                    ps.setInt(1, lista.get(i).getId_dm());
                    ps.setInt(2, codigo_oc);
                    ps.setDouble(3, lista.get(i).getCantidad_d());
                    ps.setDouble(4, v.AproximarDecimal(lista.get(i).getCosto_cd_d()));
                    ps.setDouble(5, v.AproximarDecimal(lista.get(i).getIva_d()));

                    ps.setDouble(7, v.AproximarDecimal(lista.get(i).getPorcentaje_descuento_d()));
                    ps.setDouble(8, v.AproximarDecimal(lista.get(i).getExento_d()));
                    ps.setDouble(6, v.AproximarDecimal(lista.get(i).getDescuento_d()));
                    ps.executeUpdate();

                    //this.cambiarEstadoSolicitud(lista.get(i).getId_d());
                    ps.close();
                    cnn.close();
                } else {
                    PreparedStatement ps = null;
                    Connection cnn = null;
                    cnn = cConexion.conectar();
                    ps = cnn.prepareStatement(SQLOrdenCompra.updateDetaOrdenCompra);
                    ps.setInt(1, lista.get(i).getId_dm());
                    ps.setInt(2, codigo_oc);
                    ps.setDouble(3, lista.get(i).getCantidad_d());
                    ps.setDouble(4, v.AproximarDecimal(lista.get(i).getCosto_cd_d()));
                    ps.setDouble(5, v.AproximarDecimal(lista.get(i).getIva_d()));
                    ps.setDouble(6, v.AproximarDecimal(lista.get(i).getDescuento_d()));
                    ps.setDouble(7, v.AproximarDecimal(lista.get(i).getPorcentaje_descuento_d()));
                    ps.setDouble(8, v.AproximarDecimal(lista.get(i).getExento_d()));

                    ps.setInt(9, lista.get(i).getId_d());
                    ps.executeUpdate();
                    ps.close();
                    cnn.close();
                }
            }
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    private void cambiarEstadoSolicitud(Integer id_d) throws Exception {
        try {
            /*Actualizar Solicitud Material detalle*/
            PreparedStatement ps = cConexion.conectar().prepareCall(SQLOrdenCompra.actualizaDetalleSolicitud);
            ps.setInt(1, id_d);
            ps.executeUpdate();

            ps.close();
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public void aprobarOrdenCompra(OrdenCompra oc) throws Exception {
        try {
            this.cambiarEstado("AP", oc.getId_oc());
            Mensaje m = new Mensaje();
            m.messageInfo(m.getIinformation());
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public void denegarOrdenCompra(OrdenCompra oc) throws Exception {
        try {
            this.cambiarEstado("D", oc.getId_oc());
            BitacoraControlador bc = new BitacoraControlador();
            bc.setBitacoraAnulacion(oc.getId_oc(), bc.denegarOrdenCompra + ": " + oc.getNumero_oc(), bc.denegarOrdenCompra);

            Mensaje m = new Mensaje();
            m.messageInfo(m.getIdenegada());
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public OrdenCompra ConsultaOrdenCompraEnca(int codigo_orden_compra) throws Exception {

        try {
            PreparedStatement pstm = null;
            pstm = cConexion.conectar().prepareStatement(SQLOrdenCompra.buscarEncaOrdenCompra);
            pstm.setInt(1, codigo_orden_compra);
            ResultSet rs = pstm.executeQuery();

            OrdenCompra oc = new OrdenCompra();
            while (rs.next()) {
                oc.setId_oc(rs.getInt("id_oc"));
                oc.setFecha_oc(rs.getDate("fecha_oc"));
                oc.setNumero_oc(rs.getInt("numero_oc"));
                oc.setBloque_oc(rs.getInt("bloque_oc"));
                oc.setFechahora_oc(rs.getTime("fechahora"));
                oc.setEstado_oc(rs.getString("estado_oc"));
                oc.setTipo_oc(rs.getString("tipo_oc"));
                oc.setPercepcion_oc(rs.getDouble("percepcion_oc"));
                oc.setId_em(rs.getInt("id_em")); //Empresa
                oc.setNombre_p(rs.getString("nombre_em"));//nombre_em es el nombre de la Empresa Redetal o Intesal

                oc.setId_p(rs.getInt("id_p")); //proveedor
                oc.setNombre_em(rs.getString("empresa_p"));//empresa_p es el  nombre del proveedor
                oc.setAplica_percepcion_p(rs.getString("aplicar_percepcion_p"));
                oc.setNit_p(rs.getString("nit_p"));
            }
            return oc;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public void modificarOrdenCompra(OrdenCompra oc) throws Exception {
        try {
            SessionControlador sc = new SessionControlador();
            sc.redireccionar_Codigo_Proceso_Modifcar(oc.getId_oc(), RutaProyecto.wfrmOrdenCompra);
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public void anularOrdenCompra(OrdenCompra oc) throws Exception {
        try {
            BitacoraControlador bc = new BitacoraControlador();
            bc.setBitacoraAnulacion(oc.getId_oc(), bc.anulacionOrdenCompra + ": " + oc.getNumero_oc(), bc.anulacionOrdenCompra);
            this.cambiarEstado("A", oc.getId_oc());

            Mensaje m = new Mensaje();
            m.messageInfo(m.getIanulada());
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public void eliminarItem(OrdenCompra oc) throws Exception {

        Connection cnn = null;
        PreparedStatement ps = null;
        try {
            MaterialControlador mc = new MaterialControlador();
            BitacoraControlador bc = new BitacoraControlador();

            cnn = cConexion.conectar();
            ps = cnn.prepareStatement(SQLOrdenCompra.eliminarDetaOrdenCompraItem);
            ps.setInt(1, oc.getId_d());
            ps.executeUpdate();

            mc.setCantidadMaterial_Aumentar_Disminuir(oc.getId_oc(), oc.getId_dm(), oc.getCantidad_d(), "D", bc.eliminarItemOrdenCompra + ": " + oc.getNumero_oc(), oc.getNumero_oc().toString(), bc.eliminarItemOrdenCompra);
            bc.setBitacoraAnulacion(oc.getId_oc(), bc.eliminarItemOrdenCompra + ": " + oc.getNumero_oc(), bc.eliminarItemOrdenCompra);

            ps.close();
            cnn.close();

            Mensaje m = new Mensaje();
            m.messageInfo(m.getIeliminada());

        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public void cambiarEstado(String estado, Integer codigo_oc) throws Exception {
        try {
            PreparedStatement ps = cConexion.conectar().prepareStatement(SQLOrdenCompra.cambiarEstadoOrdenCompra);
            ps.setString(1, estado);
            ps.setInt(2, codigo_oc);
            ps.executeUpdate();
            ps.close();

        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public Boolean validar_estado_accion_modificar(Integer id_oc) throws Exception {
        //Valida si tiene permisos para modificar o anular una orden de compra
        //Solamente el AP=aprobado o P=Pendiente se puede modificar
        try {
            PreparedStatement ps = cConexion.conectar().prepareStatement(SQLOrdenCompra.getEstado);
            ps.setInt(1, id_oc);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                if (rs.getString("estado_oc").equals("P") || rs.getString("estado_oc").equals("AP")) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public Boolean validar_estado_accion_anular(Integer id_oc) throws Exception {
        //Valida si tiene permisos para anular una orden de compra
        //Solamente el F=facturado, AC=Activo, D=denegado, A=anulado no puede annular una orden de compra
        try {
            PreparedStatement ps = cConexion.conectar().prepareStatement(SQLOrdenCompra.getEstado);
            ps.setInt(1, id_oc);
            ResultSet rs = ps.executeQuery();

            while (rs.next()) {
                if (rs.getString("estado_oc").equals("F") || rs.getString("estado_oc").equals("AC") || rs.getString("estado_oc").equals("D") || rs.getString("estado_oc").equals("A")) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public List<OrdenCompra> getConsulta_EncaOrdenCompra(OrdenCompra co) throws Exception {
        List<OrdenCompra> lista = new ArrayList<OrdenCompra>();
        Connection cnn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            cnn = cConexion.conectar();

            String var_estado = " and oc.estado_oc not in ('A') ";
            String var_fechas = this.getFiltro_Fechas(co);
            String var_proveedor = this.getFiltro_Proveedor(co);

            if (co.getEstado_oc() != null) {
                var_estado = "and oc.estado_oc='" + co.getEstado_oc() + "' ";
            }
            if (co.getFiltrar_estado() == true) {
                var_estado = " "; //trae todos los estados.
            }
            String sql = "SELECT oc.*,em.*,p.*,s.nombre_s,u.usuario_u,u.id_u,s.codigo_s FROM ORDEN_COMPRA as oc,EMPRESA as em,PROVEEDOR as p,USUARIO as u,SUCURSAL as s where p.id_p=oc.id_p and em.id_em=oc.id_em and u.id_u=oc.id_u and s.codigo_s=oc.codigo_s " + var_estado + var_fechas + var_proveedor + "order by oc.fecha_oc,oc.tipo_oc,oc.numero_oc,p.empresa_p,oc.estado_oc ";
            ps = cnn.prepareStatement(sql);
            rs = ps.executeQuery();

            while (rs.next()) {
                OrdenCompra oc = new OrdenCompra();

                /*ENCA*/
                oc.setId_oc(rs.getInt("id_oc"));
                oc.setFecha_oc(rs.getDate("fecha_oc"));
                oc.setFechahora_oc(rs.getTime("fechahora"));

                oc.setTipo_oc(rs.getString("tipo_oc"));
                oc.setNumero_oc(rs.getInt("numero_oc"));
                oc.setPercepcion_oc(rs.getDouble("percepcion_oc"));
                //oc.setPlazo_oc(rs.getInt("plazo_oc"));
                oc.setEstado_oc(rs.getString("estado_oc"));

                /*EMPRESA*/
                oc.setNombre_em(rs.getString("nombre_em"));
                oc.setId_em(rs.getInt("id_em"));

                /*USUARIO*/
                oc.setId_u(rs.getInt("id_u"));
                oc.setUsuario_u(rs.getString("usuario_u"));

                /*PROVEEDOR*/
                oc.setId_p(rs.getInt("id_p"));
                oc.setNombre_p(rs.getString("empresa_p"));
                lista.add(oc);
            }

            return lista;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public List<OrdenCompra> getDeta_OrdenCompra(Integer codigo_oc) throws Exception {

        List<OrdenCompra> lista = new ArrayList<OrdenCompra>();
        Connection cnn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            cnn = cConexion.conectar();
            ps = cnn.prepareStatement(SQLOrdenCompra.getConsulta_DetaOrdenCompra);
            ps.setInt(1, codigo_oc);
            rs = ps.executeQuery();

            cVarios v = new cVarios();
            while (rs.next()) {
                OrdenCompra oc = new OrdenCompra();

                oc.setId_d(rs.getInt("id_d"));
                oc.setId_dm(rs.getInt("id_dm"));
                oc.setId_oc(rs.getInt("id_oc"));

                oc.setCantidad_d(rs.getDouble("cantidad_d"));
                oc.setCosto_d(v.AproximarDecimal(rs.getDouble("costo_d")));
                oc.setIva_d(v.AproximarDecimal(rs.getDouble("iva_d")));
                oc.setDescuento_d(v.AproximarDecimal(rs.getDouble("descuento_d")));
                oc.setCosto_d(v.AproximarDecimal(rs.getDouble("costo_d")));
                oc.setCosto_cd_d(v.AproximarDecimal(rs.getDouble("costo_d")));
                oc.setCosto_sd_d(v.AproximarDecimal(oc.getCosto_d() + oc.getDescuento_d()));
                oc.setPorcentaje_descuento_d(v.AproximarDecimal(rs.getDouble("porcentaje_descuento_d")));
                oc.setExento_d(v.AproximarDecimal(rs.getDouble("exento_d")));
                //c.setSubTotal_c(v.AproximarDecimal( (c.getCantidad_d() * c.getCosto_d()) + (1 - c.getPorcentaje_descuento_d()) + c.getExentos_d() + c.getIva_d()));
                oc.setSubTotal_d(v.AproximarDecimal((oc.getCantidad_d() * oc.getCosto_d()) + oc.getExento_d() + oc.getIva_d()));

                /*MATERIAL */
                oc.setNombre_m(rs.getString("nombre_m"));
                lista.add(oc);
            }
            return lista;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    private String getFiltro_Fechas(OrdenCompra oc) {
        try {
            String var_fechas = " ";
            if (oc.getFecha_i() != null && oc.getFecha_f() == null) {
                var_fechas = " and oc.fecha_oc >='" + cVarios.getFecha(oc.getFecha_i()) + "' ";
            } else if (oc.getFecha_f() != null && oc.getFecha_i() == null) {
                var_fechas = " and oc.fecha_oc <='" + cVarios.getFecha(oc.getFecha_f()) + "' ";
            } else if (oc.getFecha_i() == null && oc.getFecha_f() == null) {
                var_fechas = " ";
            } else {
                var_fechas = " and oc.fecha_oc between '" + cVarios.getFecha(oc.getFecha_i()) + "' and '" + cVarios.getFecha(oc.getFecha_f()) + "' ";
            }
            return var_fechas;
        } catch (Exception e) {
            return " ";
        }
    }

    private String getFiltro_Proveedor(OrdenCompra oc) {
        try {
            String var_proveedor = " and p.id_p=" + oc.getId_p() + " ";

            if (oc.getId_p() == null) {
                var_proveedor = " ";//trae todos los proveedores.
            }
            return var_proveedor;
        } catch (Exception e) {
            return " ";
        }
    }

    public Integer getMax() throws Exception {
        try {
            ResultSet rs = cConexion.conectar().prepareStatement(SQLOrdenCompra.getMax).executeQuery();
            rs.next();
            return rs.getInt("max");
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    public OrdenCompra getTotales_x_OrdenCompra(Integer codigo_ordenCompra) throws Exception {

        try {
            PreparedStatement ps = cConexion.conectar().prepareStatement(SQLOrdenCompra.getTotales_x_OrdenCompra);
            ps.setInt(1, codigo_ordenCompra);
            ResultSet rs = ps.executeQuery();

            cVarios v = new cVarios();
            OrdenCompra c = new OrdenCompra();
            while (rs.next()) {
                c.setTotalCosto_oc(v.AproximarDecimal(rs.getDouble("total_costo_cd")));
                c.setTotal_descuento_oc(v.AproximarDecimal(rs.getDouble("total_descuento")));
                c.setTotal_exento_oc(v.AproximarDecimal(rs.getDouble("total_exento")));
                c.setTotal_iva_oc(v.AproximarDecimal(rs.getDouble("total_iva")));
                c.setTotal_costo_sd_oc(v.AproximarDecimal(rs.getDouble("total_costo_sd")));
                c.setTotal_costo_cd_oc(v.AproximarDecimal(rs.getDouble("total_costo_cd")));

                c.setSubTotal(v.AproximarDecimal(rs.getDouble("sub_total_orden_compra")));
                c.setTotal_subTotal_oc(v.AproximarDecimal(rs.getDouble("sub_total_orden_compra")));
                c.setTotal_percepcion_oc(v.AproximarDecimal(rs.getDouble("total_percepcion")));
                c.setTotal_oc(v.AproximarDecimal(rs.getDouble("total_orden_compra")));
            }
            ps.close();
            rs.close();
            return c;
        } catch (Exception e) {
            throw new Exception(e);
        }

    }

    /*REPORTES*/
}
